const xlsx = require('node-xlsx');
const fs = require('fs');
const path = require('path');
var LZString = require('lz-string');

let excelFolderPath = './excel';
let jsonFolderPath = './json';
let classFolderPath = './class';

if (process.argv[2]) {
    excelFolderPath = process.cwd() + process.argv[2]
}
if (process.argv[3]) {
    jsonFolderPath = process.cwd() + process.argv[3]
}
if (process.argv[4]) {
    classFolderPath = process.cwd() + process.argv[4]
} else if (process.argv[3]) {
    classFolderPath = process.cwd() + process.argv[3]
}
const isCompress = process.argv.find(i => i == "--compress")

function deleteFilesInFolder(folderPath) {
    // 读取文件夹中的所有文件和子文件夹
    const files = fs.readdirSync(folderPath);

    // 遍历文件和子文件夹
    files.forEach((file) => {
        const filePath = path.join(folderPath, file);

        // 检查文件的类型
        const stats = fs.statSync(filePath);
        if (stats.isFile()) {
            // 如果是文件，则删除
            fs.unlinkSync(filePath);
            //console.log(`已删除文件: ${filePath}`);
        } else if (stats.isDirectory()) {
            // 如果是文件夹，则递归调用删除函数
            deleteFilesInFolder(filePath);
        }
    });
}

function parseValue(value, type) {
    type = type.toLowerCase();
    switch (type) {
        case 'string':
            return String(value || "");
        case 'number':
            return Number(value);
        case 'boolean':
        case 'bool':
            return !!(value && type.toLowerCase() != 'false' && value != '0');
        case 'array':
            //return JSON.parse(value);
            if (!value) {
                return [];
            }
            return eval(`(${value})`);
        case 'object':
            //return JSON.parse(value);
            return eval(`(${value})`);
        default:
            return value;
    }
}

function getTypeScriptType(obj) {
    const type = typeof obj;

    if (type === 'object') {
        if (Array.isArray(obj)) {
            const arrayType = getTypeScriptType(obj[0]);
            return `${arrayType}[]`;
        } else if (obj === null) {
            return 'null';
        } else {
            const properties = Object.entries(obj).map(([key, value]) => {
                const propertyType = getTypeScriptType(value);
                return `${key}: ${propertyType}`;
            });
            return `{ ${properties.join(', ')} }`;
        }
    } else {
        return type;
    }
}


/**确认class文件夹是否存在 */
if (!fs.existsSync(classFolderPath)) {
    fs.mkdirSync(classFolderPath, { recursive: true });
}
/**删除class文件夹下所有文件 */
deleteFilesInFolder(classFolderPath)
/**确认json文件夹是否存在 */
if (!fs.existsSync(jsonFolderPath)) {
    fs.mkdirSync(jsonFolderPath, { recursive: true });
}
/**删除json文件夹下所有文件 */
deleteFilesInFolder(jsonFolderPath)

function parseSheetName(name) {
    const nameArr = name.split('|');
    if (nameArr.length > 1) {
        return nameArr[1];
    } else {
        return nameArr[0];
    }
}

function handleTableSheet(sheet, filePath) {
    const sheetName = parseSheetName(sheet.name);
    const jsonData = [];
    /**字段名 */
    const keys = sheet.data[0];
    /**描述 */
    const descs = sheet.data[1];
    /**数据类型 */
    const types = sheet.data[2];


    //console.log(`开始导出: ${sheetName}`);
    // 遍历每行数据
    for (let row = 3; row < sheet.data.length; row++) {


        const record = {};
        for (let col = 0; col < keys.length; col++) {

            const key = keys[col];
            const type = types[col];
            const rowData = sheet.data[row];
            const value = rowData[col];

            if (!keys[col] || !rowData[0]) {
                //过滤掉第一行或第一列是空的
                continue;
            }
            if (!type) {
                throw (`type is null in ${sheetName} row:${row} col:${col}`)
            }
            record[key] = parseValue(value, type);

        }
        if (Object.keys(record).length > 0) {
            jsonData.push(record);
        }


    }


    // 将JSON数据写入文件
    const jsonFileName = `${sheetName}.${isCompress?"txt":"json"}`;
    const jsonFilePath = path.join(jsonFolderPath, jsonFileName);

    const fileData = isCompress ? LZString.compressToUTF16(JSON.stringify(jsonData, null, 2)) : JSON.stringify(jsonData, null, 2);
    fs.writeFileSync(jsonFilePath, fileData);
    console.log(`已导出: ${path.basename(filePath)}/${sheetName} -> ${jsonFolderPath}/${jsonFileName}`);


    /**生成class文件 */
    const classFileName = `${sheetName}.ts`;
    const classFilePath = path.join(classFolderPath, classFileName);
    const classContent = `export class ${sheetName} {\n${Object.keys(jsonData[0]).map(
        (key) => {
            const keyIndex = keys.indexOf(key);
            const comment = descs[keyIndex] ? `    /**${descs[keyIndex]} */\n` : '';
            return `${comment}    ${key}: ${getTypeScriptType(jsonData[0][key])};`

        }

    ).join('\n')}\n}\n`;
    fs.writeFileSync(classFilePath, classContent);
}

function handleObjectSheet(sheet, filePath) {
    const sheetName = parseSheetName(sheet.name);
    const jsonData = {};

    // 遍历每行数据
    for (let row = 2; row < sheet.data.length; row++) {

        const rowData = sheet.data[row];
        const key = rowData[0];
        const type = rowData[1];
        const value = rowData[2];
        const desc = rowData[3];

        if (!key) {
            //过滤掉第一列是空的
            continue;
        }
        if (!type) {
            throw (`type is null in ${sheetName} row:${row}`)
        }
        jsonData[key] = parseValue(value, type);

    }

    // 将JSON数据写入文件
    const jsonFileName = `${sheetName}.${isCompress?"txt":"json"}`;
    const jsonFilePath = path.join(jsonFolderPath, jsonFileName);
    const fileData = isCompress ? LZString.compressToUTF16(JSON.stringify(jsonData, null, 2)) : JSON.stringify(jsonData, null, 2);

    fs.writeFileSync(jsonFilePath, fileData);

    console.log(`已导出: ${path.basename(filePath)}/${sheetName} -> ${jsonFolderPath}/${jsonFileName}`);

    /**生成class文件 */
    const classFileName = `${sheetName}.ts`;
    const classFilePath = path.join(classFolderPath, classFileName);
    let index = 0
    const classContent = `export class ${sheetName} {\n${Object.keys(jsonData).map(
        (key) => {
            const rowData = sheet.data[index + 2];
            const type = rowData[1];
            const value = jsonData[key];
            const desc = rowData[3];
            const comment = desc ? `    /**${desc} */\n` : '';
            index++
            return `${comment}    ${key}: ${getTypeScriptType(value)};`

        }
    ).join('\n')}\n}\n`;

    fs.writeFileSync(classFilePath, classContent);
}

// 读取Excel文件夹下的所有Excel文件
fs.readdir(excelFolderPath, (err, files) => {
    if (err) {
        console.error('Error reading excel folder:', err);
        return;
    }

    // 遍历每个Excel文件
    files.forEach(file => {
        const filePath = path.join(excelFolderPath, file);


        // 判断文件是否为Excel文件
        if (filePath.indexOf('~$') == -1 && path.extname(file) === '.xlsx' || path.extname(file) === '.xls') {
            // 读取Excel文件
            const sheets = xlsx.parse(filePath);

            // 遍历每个Sheet表
            sheets.forEach(sheet => {
                const row1 = sheet.data[0];
                if (row1[0] == 'key' && row1[1] == 'type' && row1[2] == 'value' && row1[3] == 'desc') {
                    handleObjectSheet(sheet, filePath);
                } else {
                    handleTableSheet(sheet, filePath);
                }
            });
        }
    });
});